package cn.iocoder.yudao.module.system.controller.admin.answer;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.module.system.controller.admin.answer.vo.*;
import cn.iocoder.yudao.module.system.controller.admin.answerRecord.vo.AnswerRecordSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.answer.UserAnswerDO;
import cn.iocoder.yudao.module.system.dal.dataobject.answerRecord.AnswerRecordDO;
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
import cn.iocoder.yudao.module.system.dal.dataobject.question.QuestionVo;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2AccessTokenMapper;
import cn.iocoder.yudao.module.system.service.answer.UserAnswerService;
import cn.iocoder.yudao.module.system.service.answerRecord.AnswerRecordService;
import cn.iocoder.yudao.module.system.service.question.QuestionService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import cn.iocoder.yudao.module.system.util.StringUtilExtend;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;


import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;


import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

@Tag(name = "管理后台 - 用户答案")
@RestController
@RequestMapping("/system/userAnswer")
@Validated
public class UserAnswerController {

    @Resource
    private UserAnswerService userAnswerService;
    @Resource
    private AnswerRecordService answerRecordService;
    @Resource
    private QuestionService questionService;
    @Resource
    private OAuth2AccessTokenMapper oAuth2AccessTokenMapper;
    @Resource
    private AdminUserService userService;

    @PostMapping("/create")
    @Operation(summary = "创建用户答案")
    @PreAuthorize("@ss.hasPermission('usanswer:user-answer:create')")
    public CommonResult<Integer> createUserAnswer(@Valid @RequestBody UserAnswerSaveReqVO createReqVO) {

        return success(userAnswerService.createUserAnswer(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新用户答案")
    @PreAuthorize("@ss.hasPermission('usanswer:user-answer:update')")
    public CommonResult<Boolean> updateUserAnswer(@Valid @RequestBody UserAnswerSaveReqVO updateReqVO) {
        userAnswerService.updateUserAnswer(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除用户答案")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('usanswer:user-answer:delete')")
    public CommonResult<Boolean> deleteUserAnswer(@RequestParam("id") Integer id) {
        userAnswerService.deleteUserAnswer(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得用户答案")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('usanswer:user-answer:query')")
    public CommonResult<UserAnswerRespVO> getUserAnswer(@RequestParam("id") Integer id) {
        UserAnswerDO userAnswer = userAnswerService.getUserAnswer(id);
        return success(BeanUtils.toBean(userAnswer, UserAnswerRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得用户答案分页")
    @PreAuthorize("@ss.hasPermission('usanswer:user-answer:query')")
    public CommonResult<PageResult<UserAnswerRespVO>> getUserAnswerPage(@Valid UserAnswerPageReqVO pageReqVO) {
        PageResult<UserAnswerDO> pageResult = userAnswerService.getUserAnswerPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, UserAnswerRespVO.class));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出用户答案 Excel")
    @PreAuthorize("@ss.hasPermission('usanswer:user-answer:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportUserAnswerExcel(@Valid UserAnswerPageReqVO pageReqVO,
                                      HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<UserAnswerDO> list = userAnswerService.getUserAnswerPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "用户答案.xls", "数据", UserAnswerRespVO.class,
                BeanUtils.toBean(list, UserAnswerRespVO.class));
    }

    /**
     * 查询之前的问题
     */
    @GetMapping("/getAnswer")
    public CommonResult<UserAnswerDO> getAnswer(@RequestParam("questionId") Integer questionId,
                                                @RequestParam("answerNo") Integer answerNo, HttpServletRequest request) {
        String token = request.getHeader("authorization");
        System.out.println("传来的token: " + token);
        String[] s = token.split(" ");
        OAuth2AccessTokenDO oAuth2AccessTokenDO = oAuth2AccessTokenMapper.selectByAccessToken(s[1]);
        Integer userId = oAuth2AccessTokenDO.getUserId().intValue();
        System.out.println("查询到的token解析对象: " + oAuth2AccessTokenDO);
        System.out.println("用户Id: " + oAuth2AccessTokenDO.getUserId());
        return success(userAnswerService.getOldUserAnswer(questionId, answerNo, userId));
    }

    /**
     * 提交问题
     */
    @PostMapping("/commitQuestion")
    @Transactional
    public CommonResult<Map<String, Object>> commitQuestion(@RequestBody UserAnswerParam param, HttpServletRequest request) {

        Long userId = getLoginUserId();
        AdminUserDO user = userService.getUser(userId);
        Integer answerNo = -1;
        Integer recordId = 0;
        if(param.getAnswerNo()==null) {
            param.setAnswerNo(-1);
        }
        Integer biggestNum = param.getType()==1?14:15;
        //如果是重新开始答题 就查询之前的序号 在之前的答题序号上加1
        if (param.getAnswerNo() == -1) {
            //校验次数是否足够
            if (param.getType() == 1 && user.getTestLeftTimes() < 1) {
                throw exception(TEST_VERSION_TIMES_NOT_ENOUGH);
            }
            if (param.getType() == 2 && user.getProLeftTimes() < 1) {
                throw exception(PRO_VERSION_TIMES_NOT_ENOUGH);
            }
            //扣除次数
            if (param.getType() == 1) {
                user.setTestLeftTimes(user.getTestLeftTimes() - 1);
            }
            if (param.getType() == 2) {
                user.setProLeftTimes(user.getProLeftTimes() - 1);
            }
            System.out.println("答题后的剩余次数: "+user);
            UserSaveReqVO userSaveReqVO = new UserSaveReqVO();
            BeanUtils.copyProperties(user, userSaveReqVO);
            userService.updateUser(userSaveReqVO);
            Integer biggestAnswerNo = userAnswerService.getBiggestAnswerNo(Math.toIntExact(userId));
            answerNo = biggestAnswerNo + 1;
            param.setAnswerNo(biggestAnswerNo + 1);
            //创建一个单道题的答题记录
            UserAnswerSaveReqVO createReqVO = new UserAnswerSaveReqVO();
            BeanUtils.copyProperties(param, createReqVO);
            createReqVO.setUserId(Math.toIntExact(userId));
            System.out.println("是否为空" + CollectionUtil.isNotEmpty(param.getAnswerChoices()));
            if (CollectionUtil.isNotEmpty(param.getAnswerChoices())) {
                createReqVO.setAnswerChoices(StringUtilExtend.transferListToString(param.getAnswerChoices()));
            } else {
                createReqVO.setAnswerChoices("");
            }
            userAnswerService.createUserAnswer(createReqVO);
            //创建一个整体的答题记录
            AnswerRecordSaveReqVO answerRecordSaveReqVO = new AnswerRecordSaveReqVO();
            answerRecordSaveReqVO.setUserId(Math.toIntExact(userId));
            answerRecordSaveReqVO.setLastAnswerQuestionId(param.getQuestionId());
            answerRecordSaveReqVO.setAnswerNo(biggestAnswerNo + 1);
            answerRecordSaveReqVO.setStatus(1);
            answerRecordSaveReqVO.setType(param.getType());
            recordId = answerRecordService.createAnswerRecord(answerRecordSaveReqVO);

        } else {
            answerNo = param.getAnswerNo();
            //是第二题以后的题，或者第一题的第二次修改。先判断是否存在旧题答题记录，存在就修改，不存在就直接保存。
            UserAnswerDO userAnswerDO = userAnswerService.getAnswerByUserIdAndAnswerNoAndQuestionId(Math.toIntExact(userId), param.getAnswerNo(), param.getQuestionId());
            if (userAnswerDO == null) {
                //不存在直接保存
                UserAnswerSaveReqVO createReqVO = new UserAnswerSaveReqVO();
                BeanUtils.copyProperties(param, createReqVO);
                createReqVO.setUserId(Math.toIntExact(userId));
                if (CollectionUtil.isNotEmpty(param.getAnswerChoices())) {
                    createReqVO.setAnswerChoices(StringUtilExtend.transferListToString(param.getAnswerChoices()));
                } else {
                    createReqVO.setAnswerChoices("");
                }
                userAnswerService.createUserAnswer(createReqVO);
            } else {
                //如果存在直接修改
                UserAnswerSaveReqVO updateVo = new UserAnswerSaveReqVO();
                BeanUtils.copyProperties(param, updateVo);
                updateVo.setUserId(Math.toIntExact(userId));
                updateVo.setId(userAnswerDO.getId());
                if (CollectionUtil.isNotEmpty(param.getAnswerChoices())) {
                    updateVo.setAnswerChoices(StringUtilExtend.transferListToString(param.getAnswerChoices()));
                } else {
                    updateVo.setAnswerChoices("");
                }
                userAnswerService.updateUserAnswer(updateVo);
            }

            //查询之前的组答题记录
            AnswerRecordDO answerRecordDO = answerRecordService.getByUserIdAndAnswerNo(Math.toIntExact(userId), answerNo);
            if (answerRecordDO != null) {
                recordId = answerRecordDO.getId();
            }
            //如果存在答题记录 且答题记录的问题Id小于当前问题的Id,才进行修改答题组记录
            if (answerRecordDO != null && answerRecordDO.getLastAnswerQuestionId() < param.getQuestionId()) {
                answerRecordDO.setLastAnswerQuestionId(param.getQuestionId());
                //判断是否答完最后一题
                Integer biggestQuestionId = questionService.getBiggestQuestionIdByType(answerRecordDO.getType());
                //如果当前题目的Id大于等于最大Id,说明已经答完
                if (param.getQuestionId() >= biggestNum) {
                    answerRecordDO.setStatus(2);
                } else {
                    answerRecordDO.setStatus(1);
                }
                AnswerRecordSaveReqVO answerRecordSaveReqVO = new AnswerRecordSaveReqVO();
                BeanUtils.copyProperties(answerRecordDO, answerRecordSaveReqVO);
                answerRecordService.updateAnswerRecord(answerRecordSaveReqVO);
            }
        }

        Map<String, Object> m = new HashMap<>();
        m.put("answerNo", answerNo);
        m.put("recordId", recordId);
        return success(m);
    }


}